
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* End of #ifdef __cplusplus */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <pthread.h>

#include "sample_comm.h"
#include "mpi_snap.h"

#include "cam_operation.h"
#include "video.h"
#include "snap.h"
#include <semaphore.h>

#include "time_fun.h"

#define     SAVE_STREAM 0
/******************************************************************************
* function : show usage
******************************************************************************/
void SAMPLE_SNAP_Usage(char* sPrgNm)
{
    printf("Usage : %s <index> \n", sPrgNm);
    printf("index:\n");
    printf("\t 0)double pipe offline, normal snap.\n");

    return;
}


/******************************************************************************
* function : to process abnormal case
******************************************************************************/
void SAMPLE_SNAP_HandleSig(HI_S32 signo)
{
    signal(SIGINT, SIG_IGN);
    signal(SIGTERM, SIG_IGN);

    if (SIGINT == signo || SIGTERM == signo)
    {
        SAMPLE_COMM_All_ISP_Stop();
        SAMPLE_COMM_VO_HdmiStop();
        SAMPLE_COMM_SYS_Exit();
        printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
    }
    exit(-1);
}

/*extern pthread_mutex_t mutex;
extern pthread_cond_t cond;*/
//use struct 






/******************************************************************************
* function    : main()
* Description : main
******************************************************************************/



#ifdef __HuaweiLite__
int app_main(int argc, char *argv[])
#else


int main(int argc, char* argv[])
#endif
{
    HI_S32 s32Ret = HI_FAILURE;
    HI_S32 s32Index;

    if (argc < 2)
    {
        SAMPLE_SNAP_Usage(argv[0]);
        return HI_FAILURE;
    }

#ifndef __HuaweiLite__
    signal(SIGINT, SAMPLE_SNAP_HandleSig);
    signal(SIGTERM, SAMPLE_SNAP_HandleSig);
#endif



    int fd ;
    int ret = -1;
    int cln_sock=0;

    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    int sendbytes=0, recvbytes=0;
    ret = configure_socket(&fd,&server_addr,&client_addr,&cln_sock);
    if(ret<0)
    {
        fprintf(stderr,"configure_socket err\n");
    }
    else 
    {
        fprintf(stderr, "configure success\n");
    }
    fd_set myset;
    FD_ZERO(&myset);
    FD_SET(cln_sock, &myset);
    stcamera_param  stcameraParam_;
    stcamera_return stcameraReturn_;
    ret = handshake_with_client(cln_sock,myset,&stcameraParam_);
    if(ret<0)
    {
        fprintf(stderr,"handshake_with_client err\n");
    }
    char buff[MAX_BUFF_SIZE];    
    
    pthread_t vioPtherad, snapPthread;
    /*semaphoere 极简入门教程*/
    const char *reset_vio_sema = SMEA_NAME, *snap_sema = SNAP_LOCK_NAME;
    sem_t *reset_lock , *snap_lock;    
    reset_lock = sem_open(reset_vio_sema, O_CREAT | O_EXCL, 0666, 0);
    //O_CREAT | O_EXCL -->segmentation fault
    snap_lock = sem_open(snap_sema, O_CREAT , 0666, 1);

    stcameraParam_.first_time_get_param=TRUE;
    s32Ret =SAMPLE_SNAP_DoublePipeOffline(&stcameraParam_, &stcameraReturn_); 
    stcameraParam_.first_time_get_param=FALSE;


    if( (sendbytes =tcp_send( cln_sock,  myset, (BYTE* )&stcameraParam_, sizeof(stcamera_param)) )== -1)
    {
        perror("send");
        return -1;
    }
    fprintf(stderr,"%s tcp_send %d \n",__FUNCTION__,sendbytes);

    if( (recvbytes = tcp_recv( cln_sock,  myset, (BYTE* )buff, sizeof(stcamera_param))  ==-1) )
    {
        perror("recv");
        return -1;
    }
    //如果握手回复包正确，
    fprintf(stderr,"%s %d %s \n",__FUNCTION__,__LINE__,buff);

    float tdiff =0;
    struct timespec t1,t_total;
    int RTSP_THREAD_ALIVE =0;
    BYTE *pic_buff ;
    pic_buff = (BYTE*)malloc(MAX_BUFF_SIZE);
    SNAP_init(&stcameraParam_, &stcameraReturn_);
    
    stsnap_param stsanpParam ;
    stsanpParam.stcameraReturn = &stcameraReturn_;
    stsanpParam.sem_snap = snap_lock;
    pthread_create(&snapPthread, NULL, server_snap, (void *)&stsanpParam);
    //run流程
    while(1)
    {
        

        t_total = tic();

        t1 = tic();
        if( (recvbytes = tcp_recv( cln_sock,  myset, (BYTE* )&stcameraParam_, sizeof(stcamera_param))
            == -1))
        {
            perror("recv");
            return -1;
        }                
        // fprintf(stderr,"receive %d %s %d\n", recvbytes, __FUNCTION__,__LINE__);
        //Send out triger signal to the other thread
        int status = calc_status(stcameraParam_);
        //post sem, in order to end the rtsp thread .
        // fprintf(stderr,"test %d %s %d\n", status, __FUNCTION__,__LINE__);
        toc(t1,&tdiff);
        printf("Wait client command takes time %f \n", tdiff);
        #if 0
        if(RTSP_THREAD_ALIVE  == 1) {
            sem_post(reset_lock);
            RTSP_THREAD_ALIVE = 0;
            pthread_join(vioPtherad,NULL);
        }
        
        fprintf(stderr,"test 2%s %d\n",__FUNCTION__,__LINE__);
        //
        /*switch(status)
        {
            case RTSP
        }*/

        if((status & RTSP) !=0)
        {


            const char *s = "this is setting RTSP \n";
            fprintf(stderr,"%s", s);

            //create a thread ,
            pthread_create(&vioPtherad, NULL, server_vio, (void *)&stcameraParam_);
            RTSP_THREAD_ALIVE =1;
            
        }
        #endif
        //NONBLOCK
        if((status & SNAP) != 0)
        {
            if(sem_wait(snap_lock)==-1)
            {
                printf("%s :%dget reset_vio_sema failed \n",__FUNCTION__,__LINE__); 
                
            }
            int size = tcp_send( cln_sock,  myset, (BYTE* )&stcameraReturn_, sizeof(stcamera_return));                
            // printf("index --size %d, %d \n", index, size);
            if(size <0)
                    perror("send");
            sem_post(snap_lock);

        #if 0
            t1= tic();            
            #if SAVE_STREAM
                s32Ret = SNAP_Process();
            #else 
            s32Ret = SNAP_Process_CP(&stcameraReturn_);
            #endif
            toc(t1,&tdiff);
            printf("SNAP_Process takes time %f \n", tdiff);
            if (HI_SUCCESS != s32Ret)
            {
                printf("%s: sanp process failed!\n", __FUNCTION__);                        
            }
            else
            {
                #if SAVE_STREAM
                    t1 =tic();
                    // printf("snap success!\n");
                    int fd = open(SNAP_DIR, O_RDWR);
                    int filelen = lseek(fd,0L,SEEK_END);
                    //移动到文件开头
                    lseek(fd, 0L, SEEK_SET);                        
                    // send(cln_sock, &filelen, sizeof(filelen), 0);

                    // read(fd,stcameraReturn_.pFrameBuffer,MAX_BUFF_SIZE);
                    ret = read(fd,pic_buff,filelen);                                        
                    if(ret <=0 )
                    {
                        perror("read");
                        fprintf(stderr, "%s %d read failed , size is %d",__FUNCTION__,__LINE__,ret);
                        // return
                    }
                    else{

                        // fprintf(stderr, "%s %d read  size is %d",__FUNCTION__,__LINE__,ret);
                    }
                    toc(t1,&tdiff);
                    printf("read_snap pic takes time %f \n", tdiff);
                    //

                    stcameraReturn_.FrameBufferSize = filelen;
                    memcpy(stcameraReturn_.pFrameBuffer ,pic_buff , filelen);
                    //这样就是3*SIZE_256KB
                #else
                #endif

                t1=tic();
                //int size = send(cln_sock,  &stcameraReturn_, sizeof(stcameraReturn_), 0);
                int total_size = sizeof(stcamera_return);//sizeof(stcameraReturn_);
                fprintf(stderr, "======stcamera_return size %d\n", total_size);

                int size = tcp_send( cln_sock,  myset, (BYTE* )&stcameraReturn_, total_size);
                
                // printf("index --size %d, %d \n", index, size);
                if(size <0)
                        perror("send");
                toc(t1,&tdiff);
                printf("send tcp takes time %f ,  %d\n", tdiff, size);
                // close(fd);
                

            }
        #endif
  
        }
        // send(cln_sock, &stcameraReturn_, sizeof(stcamera_return), 0);

        

        toc(t_total,&tdiff);
        printf("one whole cycle total takes time %f \n", tdiff);
        

    }
    SNAP_deinit();
    free(pic_buff);
    //end the socket
    close(cln_sock);

    return (s32Ret);
}


#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */

